import axios, { AxiosInstance, AxiosRequestConfig, AxiosResponse, InternalAxiosRequestConfig } from 'axios';
// import Crypto from '/@/utils/http/Crypto';
// import { useAppStore } from '/@/store/modules/app';
import Notification from '/@/utils/http/Notification';
// import Storage, { StorageKey } from '/@/utils/http/Storage';
import { useGlobSetting } from '/@/hooks/setting';
import { HttpLoadingControl } from '/@/utils/http/LoadingControl';
const globSetting = useGlobSetting();
const { loadingata, LoadingControl } = HttpLoadingControl();

interface Result {
  code: string;
  message: string;
  data: any;
  encrypted: boolean;
}

const Constants = {
  REQUEST_SUCCESS: 'S000000',
  REQUEST_NO_LOGIN: 'E000005',
};

class HttpRequest {
  private instance: AxiosInstance;

  constructor() {
    const serverUrl = globSetting.domainUrl;
    this.instance = axios.create({
      baseURL: serverUrl,
      responseType: 'json',
    });

    this.instance.interceptors.request.use(this.requestIntercept.bind(this));
    this.instance.interceptors.response.use(this.responseIntercept.bind(this), this.errorHandler.bind(this));
  }

  async request<T>(
    method: 'POST' | 'GET',
    url: string,
    params: { [key: string]: any },
    config: {
      encrypt?: boolean;
      headers?: any;
    } = {
      encrypt: false,
      headers: {},
    }
  ): Promise<T> {
    config.headers = {
      ...config.headers,
      'Content-Type': 'application/x-www-form-urlencoded',
      // 'Content-Type': method === 'POST' ? 'application/x-www-form-urlencoded' : 'application/json',
      satoken: localStorage.getItem('satoken'),
    };
    const finalConfig: AxiosRequestConfig = {
      url: url,
      method,
      params: method === 'POST' ? {} : params,
      data: method === 'POST' ? params : {},
      headers: config.headers || {},
    };

    if (config.encrypt) {
      finalConfig.params = await this.encryptParams(finalConfig.params);
    }

    return this.instance.request(finalConfig).then((response) => response as T);
  }

  private async encryptParams(params: { [key: string]: any }): Promise<{ [key: string]: any }> {
    // 处理请求参数的加密逻辑
    // let paramEncrypted: any = {};
    // Object.keys(params).forEach((key) => {
    //   paramEncrypted[Crypto.encrypt(key, appStore.keyInfo.key, appStore.keyInfo.iv)] = Crypto.encrypt(params[key], appStore.keyInfo.key, appStore.keyInfo.iv);
    // });
    return params;
  }

  private async decryptData(data: string): Promise<any> {
    // 处理响应参数的解密逻辑
    // data = Crypto.decrypt(data, appStore.keyInfo.key, appStore.keyInfo.iv);
    return data;
  }

  private requestIntercept(request: InternalAxiosRequestConfig): InternalAxiosRequestConfig {
    loadingata.value.requestUrl = request.url as string;
    LoadingControl();
    const headers: any = request.headers || {};
    headers['Content-Type'] = headers['Content-Type'] || 'application/json';
    request.headers = headers;

    return request;
  }

  private responseIntercept(response: AxiosResponse): AxiosResponse {
    loadingata.value.responseRes = response.config.url as string;
    LoadingControl();
    loadingata.value.responseRes = '';
    const data: Result = response.data as Result;
    if (data.code === Constants.REQUEST_SUCCESS) {
      // 请求成功
      if (data.encrypted) {
        data.data = this.decryptData(data.data);
      }
      try {
        data.data = JSON.parse(data.data);
      } catch (e) {
        console.warn(`${data.data} is not a valid JSON string`);
      }
      return data.data;
    } else {
      Notification.showNotice(data.message || '未知错误');
    }
    throw new Error(data.message || '请求失败');
  }

  private errorHandler(error: any): Promise<never> {
    if (axios.isAxiosError(error)) {
      Notification.showNotice('网络出现异常或存在其他问题，请稍后重试');
    } else {
      Notification.showNotice(error.message || '未知错误');
    }
    return Promise.reject(error);
  }

  get<T>(url: string, params: { [key: string]: any } = {}, config: { encrypt?: boolean; headers?: any } = {}): Promise<T> {
    return this.request('GET', url, params, config);
  }

  post<T>(url: string, params: { [key: string]: any } = {}, config: { encrypt?: boolean; headers?: any } = {}): Promise<T> {
    return this.request('POST', url, params, config);
  }
}

export default new HttpRequest();
